/**
 * @file         bsc_msg_rtp_common.h
 * @brief        双mcu远程块数据传输组件 —— 公共功能定义
 * @note         对外公布
 * @author       Jpz(jinpuzhao@hopechart.com, 靳普诏)
 * @data         2022-12-16
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2022-12-16    <td>1.0                   <td>Jpz             <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */

#ifndef _BSC_MSG_RTP_COMMON_H_
#define _BSC_MSG_RTP_COMMON_H_

#include "ofc/ofc_types.h"
#include "hcc/hcc_error_code_mid_bsc_msg_rtp.h"

// #define ALOG_TAG  "BscRemoteExplorer"  ///< 组件内部日志标签，依赖ALog完成日志输出
// #include "alog/a_log.h"


#ifdef __cplusplus
extern "C"
{
#endif


/* ~~~~~~~~~~~~~~~~~ 枚举值 ~~~~~~~~~~~~~~~~~~~~ */
enum TBsMsgRtpConstValTag
{
    kBsMsgRtpConstValAckPackSeq = 0,        ///< 用于区分应答包和消息包

    kBsMsgRtpConstValMsgRetrySize = 1,      ///< 记录重发次数的数据类型大小
    kBsMsgRtpConstValMsgSeqSize = 1,        ///< 记录重流水号的数据类型大小
    kBsMsgRtpConstValMsgHeadSize = 2,       ///< 每条消息包在缓存中需要添加2个字节的长度
    kBsMsgRtpConstValCacheItemCntMax = 255, ///< 缓存中最多允许存255条消息包
};
typedef enum TBsMsgRtpConstValTag TBsMsgRtpConstVal;

enum TBsMsgRtpNotifyTypeTag
{
    kBsMsgRtpNotifySentSuccessful = 0,      ///< 触发时刻: 接收到对端应答包 
    kBsMsgRtpNotifySentExceptional = 1,     ///< 触发时刻: 重发结束始终未收到对端应答
    kBsMsgRtpNotifyRecvSuccessful = 2,      ///< 触发时刻: 接收到对端消息包并发送应答包成功
    kBsMsgRtpNotifyRecvExceptional = 3,     ///< 触发时刻: 接收到对端消息包但发送应答包失败  ///< Jpz: 感觉不应该对应用公开
};
typedef enum TBsMsgRtpNotifyType TBsMsgRtpNotify;


/* ~~~~~~~~~~~~~~~~~ 函数类型 ~~~~~~~~~~~~~~~~~~~~ */

/**
 * 枚举消息回调函数
 * @param *user_param   用户传参
 * @param sent_times    剩余重发次数
 * @param *data         数据帧地址
 * @param data_size     数据长度
 * @return 
 */
typedef void (* TBsMsgRtpDoEnumCallBack)(void *user_param, UInt8 sent_times, const Int8 *data, UInt16 data_size);

/**
 * 通知事件函数类型
 * @param *user_param   用户参数
 * @param notify_type   通知类型
 * @param *data         数据帧地址
 * @return 
 */
typedef void (* TBsMsgRtpDoNotifyMethod)(void *user_param, Int8 notify_type, const Int8 *data, UInt16 data_size);

/**
 * 底层发送数据接口类型
 * @param *user_param   用户参数
 * @param *data         发送数据地址
 * @param size          数据大小
 * @return 成功 == size
 *         失败 <= 0
 */
typedef Int32 (* TBsMsgRtpDoUnderSend)(void *user_param, const Int8 *data, UInt32 size);

/**
 * 底层接收数据接口
 * @param *user_param   用户参数
 * @param *data         接收数据地址
 * @param size          数据大小
 * @return 成功 == size
 *         失败 <= 0
 */
typedef Int32 (* TBsMsgRtpDoUnderRecv)(void *user_param, Int8 *data, UInt32 size);


/* ~~~~~~~~~~~~~~~~~ 数据结构 ~~~~~~~~~~~~~~~~~~~~ */

/// 实际链路中发送的数据包格式，data[1]用于表示不定长数组。协议双方应当默认已知规定的数据长度
typedef struct TBsMsgRtpDataItemTag TBsMsgRtpDataItem;
struct TBsMsgRtpDataItemTag
{
    UInt8 seq_no;   ///< 应答包时 == 0；消息包时 > 0,向缓存拷贝后，继续读取后续数据
    Int8 data[1];   ///< 使指针指向流水号的下一个字节
};

/// 本地缓存中存储的数据格式。
typedef struct TBsMsgRtpCacheDataTag TBsMsgRtpCacheData;
struct TBsMsgRtpCacheDataTag
{
    UInt8 retry;  ///< 内部有效范围[2-255]。[0]表示无效消息 [1]表示最后一次等待应答状态
    TBsMsgRtpDataItem data;
};

/// 发送缓存对象数据结构
typedef struct TBsMsgRtpTxCacheTag TBsMsgRtpTxCache;
struct TBsMsgRtpTxCacheTag
{
    UInt8 *item_pos_;  ///< 当前待发送数据帧指针。每次执行发送停在被迫中止的数据项上
    UInt8 *item_end_;  ///< 发送缓存无效位
    UInt8 seq_no_;  ///< 流水号 [1:255]，[0]作应答号。
    Int8  reseve[3];  ///< 保留
};


#ifdef __cplusplus
}  ///< extern "C"
#endif

#endif  ///< _BSC_MSG_RTP_COMMON_H_


